package org.jeecg.common.security;

import org.jeecg.common.exception.JeecgBootException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 
 * @author: qiang.zhou
 * @date: 2024/6/3 15:24
 **/
@Component
@ConditionalOnProperty(name = "soc.data-security.type", havingValue = "AES")
public class AESDataSecurityImpl implements DataSecurity {

    private static final Charset UTF_8 = StandardCharsets.UTF_8;

    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    @Value("${soc.data-security.aes.key:15a10fc2e083446b}")
    private String aesKey;

    public AESDataSecurityImpl() {
    }

    @Override
    public String encrypt(String data) {
        byte[] bytes = this.encrypt(data.getBytes(UTF_8));
        return Base64Utils.encodeToString(bytes);
    }

    @Override
    public byte[] encrypt(byte[] data) {
        return this.encrypt(data, this.aesKey);
    }

    public String encrypt(String data, String key) {
        byte[] bytes = this.encrypt(data.getBytes(UTF_8), key);
        return Base64Utils.encodeToString(bytes);
    }

    public byte[] encrypt(byte[] data, String key) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(1, new SecretKeySpec(key.getBytes(UTF_8), "AES"));
            return cipher.doFinal(data);
        } catch (BadPaddingException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException var4) {
            throw new JeecgBootException(var4);
        }
    }

    @Override
    public String decrypt(String data) {
        byte[] bytes = Base64Utils.decodeFromString(data);
        bytes = this.decrypt(bytes);
        return new String(bytes, UTF_8);
    }

    @Override
    public byte[] decrypt(byte[] data) {
        return this.decrypt(data, this.aesKey);
    }

    public byte[] decrypt(byte[] data, String key) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(UTF_8), "AES");
            cipher.init(2, secretKeySpec);
            return cipher.doFinal(data);
        } catch (BadPaddingException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException var5) {
            throw new SecurityException(var5);
        }
    }

    public String decrypt(String data, String key) {
        byte[] bytes = Base64Utils.decodeFromString(data);
        bytes = this.decrypt(bytes, key);
        return new String(bytes, UTF_8);
    }

    @Override
    public String getKey() {
        throw new JeecgBootException("不支持得操作");
    }

    @Override
    public BigInteger getModulus() {
        throw new JeecgBootException("不支持得操作");
    }

    @Override
    public BigInteger getPublicExponent() {
        throw new JeecgBootException("不支持得操作");
    }
}
